// Package middleware pkg/middleware/monitor.go
package middleware

import (
	"runtime"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/shirou/gopsutil/v3/cpu"
	"github.com/shirou/gopsutil/v3/mem"
	"go.uber.org/zap"
	"gozrd-admin-api/pkg/logger"
)

var (
	// 监控数据收集间隔
	monitorInterval = 30 * time.Second
)

// SystemStats 系统统计信息
type SystemStats struct {
	// 内存统计
	Alloc        uint64 `json:"alloc"`          // 当前分配的内存
	TotalAlloc   uint64 `json:"total_alloc"`    // 从启动到现在分配的总内存
	Sys          uint64 `json:"sys"`            // 从系统获取的内存
	NumGC        uint32 `json:"num_gc"`         // GC次数
	PauseTotalNs uint64 `json:"pause_total_ns"` // GC暂停总时间
	NumGoroutine int    `json:"num_goroutine"`  // 协程数量

	// 系统统计
	MemPercent float64 `json:"mem_percent"` // 系统内存使用率
	CPUPercent float64 `json:"cpu_percent"` // CPU使用率
	TotalMem   uint64  `json:"total_mem"`   // 系统总内存
	UsedMem    uint64  `json:"used_mem"`    // 系统已用内存
}

// CollectSystemStats 收集系统统计信息
func CollectSystemStats() SystemStats {
	var stats SystemStats
	var memStats runtime.MemStats

	// 收集Go程序的内存统计
	runtime.ReadMemStats(&memStats)
	stats.Alloc = memStats.Alloc
	stats.TotalAlloc = memStats.TotalAlloc
	stats.Sys = memStats.Sys
	stats.NumGC = memStats.NumGC
	stats.PauseTotalNs = memStats.PauseTotalNs
	stats.NumGoroutine = runtime.NumGoroutine()

	// 收集系统内存统计
	if v, err := mem.VirtualMemory(); err == nil {
		stats.MemPercent = v.UsedPercent
		stats.TotalMem = v.Total
		stats.UsedMem = v.Used
	}

	// 收集CPU统计
	if cpuPercent, err := cpu.Percent(time.Second, false); err == nil && len(cpuPercent) > 0 {
		stats.CPUPercent = cpuPercent[0]
	}

	return stats
}

// StartMonitor 启动系统监控
func StartMonitor() {
	go func() {
		ticker := time.NewTicker(monitorInterval)
		defer ticker.Stop()

		for range ticker.C {
			stats := CollectSystemStats()

			// 记录监控信息
			logger.Info("系统监控",
				zap.Uint64("alloc_mb", stats.Alloc/1024/1024),
				zap.Uint64("total_alloc_mb", stats.TotalAlloc/1024/1024),
				zap.Uint64("sys_mb", stats.Sys/1024/1024),
				zap.Uint32("num_gc", stats.NumGC),
				zap.Uint64("pause_total_ms", stats.PauseTotalNs/1000000),
				zap.Int("goroutines", stats.NumGoroutine),
				zap.Float64("mem_usage_percent", stats.MemPercent),
				zap.Float64("cpu_usage_percent", stats.CPUPercent),
			)
		}
	}()
}

// Monitor 系统监控中间件
func Monitor() gin.HandlerFunc {
	// 启动后台监控协程
	StartMonitor()

	// 创建一个map用于存储请求计数
	var requestCount int64 = 0

	return func(c *gin.Context) {
		// 请求计数增加
		requestCount++

		// 处理请求
		c.Next()

		// 每1000个请求记录一次当前状态
		if requestCount%1000 == 0 {
			stats := CollectSystemStats()
			logger.Info("请求监控检查点",
				zap.Int64("request_count", requestCount),
				zap.Int("goroutines", stats.NumGoroutine),
				zap.Uint64("alloc_mb", stats.Alloc/1024/1024),
				zap.Float64("mem_usage_percent", stats.MemPercent),
				zap.Float64("cpu_usage_percent", stats.CPUPercent),
			)
		}
	}
}
